Thread Synchronization এবং Inter-thread Communication

Java Technologies - Java.lang প্যাকেজ (Java.lang Package) - Thread এবং Runnable ইন্টারফেস
319

Java-তে thread synchronization এবং inter-thread communication হলো দুইটি গুরুত্বপূর্ণ ধারণা যা multithreading প্রোগ্রামিংয়ে ব্যবহৃত হয়। এগুলি একাধিক থ্রেডের মধ্যে সঠিক সমন্বয় এবং তথ্যের নিরাপদ আদান-প্রদান নিশ্চিত করার জন্য প্রয়োজনীয়।


1. Thread Synchronization

Thread Synchronization হল একটি প্রক্রিয়া যার মাধ্যমে একাধিক থ্রেডের মধ্যে রেস কন্ডিশন (race condition) এবং ডেটা ইনকনসিস্টেন্সি প্রতিরোধ করা হয়। যখন একাধিক থ্রেড একই রিসোর্সে একসাথে অ্যাক্সেস করে, তখন সঠিকভাবে থ্রেডগুলির কার্যক্রম সিঙ্ক্রোনাইজ করা প্রয়োজন যাতে তারা একে অপরের ডেটার উপর প্রভাব না ফেলে।

Synchronization এর প্রয়োজনীয়তা:

  • Race Condition: যখন একাধিক থ্রেড একই রিসোর্স (যেমন ভেরিয়েবল বা অবজেক্ট) একসাথে অ্যাক্সেস করে এবং তাদের কার্যক্রম সঠিকভাবে সমন্বিত না হয়, তখন তা race condition সৃষ্টি করতে পারে।
  • Data Consistency: একাধিক থ্রেড একে অপরের সাথে ঠিকভাবে সমন্বয় না করলে, ডেটার অবস্থা অপরিবর্তিত থাকতে পারে না।

Synchronization এর কৌশল:

Java-তে থ্রেড সিঙ্ক্রোনাইজ করতে synchronized কিওয়ার্ড ব্যবহার করা হয়।

1.1. Method Level Synchronization:
  • একটি মেথডকে synchronized করার মাধ্যমে, শুধুমাত্র একটি থ্রেড সেই মেথডে এক্সিকিউট করার অনুমতি পায়। অন্যথায়, অন্য কোন থ্রেড মেথডটি এক্সিকিউট করতে পারবে না যতক্ষণ না প্রথম থ্রেডটি সম্পূর্ণভাবে কাজটি শেষ করে।
class Counter {
    private int count = 0;

    // Synchronized method
    public synchronized void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

public class SynchronizedExample {
    public static void main(String[] args) {
        Counter counter = new Counter();

        // Thread 1
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });

        // Thread 2
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });

        t1.start();
        t2.start();

        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Final Count: " + counter.getCount());
    }
}

ব্যাখ্যা:

  • increment() মেথডটি synchronized হওয়ায়, একবারে এক থ্রেডই সেটি এক্সিকিউট করতে পারে। এক থ্রেড কাজ শেষ না করা পর্যন্ত অন্য থ্রেড এটি এক্সিকিউট করতে পারবে না।
  • এইভাবে race condition এড়ানো হয়।
1.2. Block Level Synchronization:
  • কখনো কখনো আপনি পুরো মেথডের পরিবর্তে একটি নির্দিষ্ট ব্লককে সিঙ্ক্রোনাইজ করতে চাইবেন, যাতে কিছু অংশের জন্য একাধিক থ্রেড এক্সিকিউট করতে পারে এবং কিছু অংশ শুধুমাত্র এক থ্রেডই এক্সিকিউট করতে পারে।
class Counter {
    private int count = 0;

    public void increment() {
        synchronized (this) {
            count++;
        }
    }

    public int getCount() {
        return count;
    }
}

ব্যাখ্যা:

  • এখানে synchronized ব্লক ব্যবহার করা হয়েছে যা শুধুমাত্র count++ কোড ব্লকটিকে সিঙ্ক্রোনাইজ করবে, ফলে অন্যান্য কোড একসাথে এক্সিকিউট করা যাবে।

2. Inter-thread Communication

Inter-thread Communication হল সেই প্রক্রিয়া যার মাধ্যমে একাধিক থ্রেডের মধ্যে যোগাযোগ করা হয় এবং তারা একে অপরের সাথে সমন্বয় করতে পারে। Java-তে, inter-thread communication করার জন্য তিনটি মূল মেথড ব্যবহার করা হয়:

  1. wait()
  2. notify()
  3. notifyAll()

এই মেথডগুলো মূলত Object ক্লাসের অন্তর্গত এবং এই মেথডগুলো শুধুমাত্র synchronized ব্লকের মধ্যে ব্যবহার করা যেতে পারে।

2.1. wait() মেথড:

  • এটি একটি থ্রেডকে wait বা ব্লক করে রাখে যতক্ষণ না অন্য কোনো থ্রেড তাকে notify করে দেয়।
  • wait() মেথডটি তখনই ব্যবহার করা যেতে পারে যখন থ্রেডের কোনো নির্দিষ্ট অবস্থার পূর্ণতার জন্য অপেক্ষা করতে হয়।

2.2. notify() মেথড:

  • এটি একটি থ্রেডকে notify করে যে সে তার কাজ শেষ করতে পারে এবং wait করা থ্রেডটি পুনরায় কাজ শুরু করতে পারে।

2.3. notifyAll() মেথড:

  • এটি সমস্ত wait করা থ্রেডকে notify করে।

Inter-thread Communication Example:

এখানে দুটি থ্রেডের মধ্যে wait() এবং notify() ব্যবহারের একটি উদাহরণ দেয়া হল, যেখানে একটি থ্রেড অপেক্ষা করবে এবং অন্য থ্রেড তাকে notify করবে।

class Processor {
    private boolean isProcessed = false;

    // Method that simulates waiting for a task to be processed
    public synchronized void produce() throws InterruptedException {
        while (isProcessed) {
            wait();  // Wait until the task is consumed
        }
        System.out.println("Producing item...");
        isProcessed = true;
        notify();  // Notify the consumer that the task is done
    }

    // Method that simulates consuming the task
    public synchronized void consume() throws InterruptedException {
        while (!isProcessed) {
            wait();  // Wait until the task is produced
        }
        System.out.println("Consuming item...");
        isProcessed = false;
        notify();  // Notify the producer that the task is done
    }
}

public class InterThreadCommunicationExample {
    public static void main(String[] args) {
        Processor processor = new Processor();

        // Producer Thread
        Thread producer = new Thread(() -> {
            try {
                while (true) {
                    processor.produce();
                    Thread.sleep(1000);  // Simulating time taken for producing
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // Consumer Thread
        Thread consumer = new Thread(() -> {
            try {
                while (true) {
                    processor.consume();
                    Thread.sleep(1000);  // Simulating time taken for consuming
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        producer.start();
        consumer.start();
    }
}

ব্যাখ্যা:

  • Producer থ্রেড produce() মেথডের মধ্যে wait() ব্যবহার করে, যতক্ষণ না consume() মেথড থেকে notify() করা হয়।
  • Consumer থ্রেড consume() মেথডে wait() ব্যবহার করে, যতক্ষণ না produce() মেথড থেকে notify() করা হয়।
  • notify() বা notifyAll() এর মাধ্যমে থ্রেডগুলোর মধ্যে সমন্বয় করা হয়।

নোট:

  • Deadlock: সিঙ্ক্রোনাইজেশন এবং inter-thread communication ব্যবহারের সময় deadlock সমস্যা হতে পারে যদি দুইটি থ্রেড একে অপরের জন্য অপেক্ষা করে থাকে। এই পরিস্থিতি এড়াতে সঠিক synchronization এবং locking মেকানিজম ব্যবহার করতে হবে।
  • Thread Safety: Synchronization ব্যবহার করা না হলে একাধিক থ্রেড একই রিসোর্সে একসাথে অ্যাক্সেস করতে গিয়ে ডেটার অবস্থা অপরিবর্তিত থাকতে পারে, যা race condition তৈরি করে।

  • Thread Synchronization ব্যবহারের মাধ্যমে আপনি একাধিক থ্রেডের মধ্যে সমন্বয় নিশ্চিত করতে পারেন এবং race conditions থেকে মুক্ত থাকতে পারেন।
  • Inter-thread Communication-এর মাধ্যমে বিভিন্ন থ্রেডের মধ্যে নিরাপদে তথ্য আদান-প্রদান করা সম্ভব হয়। wait(), notify(), এবং notifyAll() মেথডগুলি এই প্রক্রিয়াকে সহজ করে তোলে।
Content added By
Promotion
NEW SATT AI এখন আপনাকে সাহায্য করতে পারে।

Are you sure to start over?

Loading...